With authentication, it should be no surprise that
the client providing credentials to the service is a common scenario.
Two questions must be addressed: which credentials should be used and
how they should be provided.
Table 1 shows a list of eight possible values, and a description of each one, for the client credential type.
Table 1. Client Credential Types for Message Security
Credential Type | Description |
---|
Certificate | The client provides a certificate for the service to authenticate. The ClientCredentials property on the proxy exposes a ClientCertificate object. By calling the SetCertificate method, the certificate can be retrieved from a particular certificate store. |
IssuedToken | Authentication
is provided by a central token-issuing service. Prior to making a
request to a service, the client requests a security token from the
central service. That token is then provided to the service, which will
validate it against the same service to authenticate the requester. |
None | No authentication information is provided by the client. This is the equivalent of anonymous access to the service. |
UserName | The
client is authenticated by providing a username and password. There is
no way to configure the values used in this credential type. They must
be provided through code by assigning the UserName and Password properties of the UserName property on the proxy’s ClientCredentials property.
proxy.ClientCredentials.UserName.UserName = "user" proxy.ClientCredentials.UserName.Password = "password"
|
Windows | The credentials for the currently logged-on Windows users are provided to the service for authentication. |
Although this is a list
of the possible sources for the client credentials, not all types are
valid for all bindings. The client credential type used depends on the
security mode required by the service. If the binding is using
transport security, the client credentials must use Windows credentials
or certificates. If the binding supports message security, the list of
possible client credentials increases. The values that appear in Table 8-1 are valid for specifying message-level security for every binding type with the sole exception of the basicHttpBinding binding, which supports UserName and Certificate only.
You can specify which
credential type to use, either imperatively or declaratively. The
declarative technique is illustrated in the configuration element that
follows:
<binding name="myBinding">
<security mode="Message">
<message clientCredentialType="Certificate"/>
</security>
</binding>
Note that the security mode
has been set to message level. It’s important to be aware that
additional message security elements can be applied to different
binding types. In other words, in some instances, merely setting the
client credential type is not sufficient.
Note: The default value for the clientCredentialType is Windows.
An important aspect in the Microsoft certification exam is to be aware
of some of the criteria for the answers. It is not possible for a
correct answer to a certification exam question to be "don’t do
anything." This means that you should never have "set clientCredentialType for message security to Windows" as part of the correct answer to any question.
Now that the fundamentals of message-level security have been addressed, the next sections detail one credential type at a time.
1. Certificate Credentials
When the certificate
credential type is specified, the client provides a certificate to the
service for authentication. Because the service must perform the
authentication, start by looking at the configuration for the service:
<behaviors>
<serviceBehaviors>
<behavior name="ServiceCredentialsBehavior">
<serviceCredentials>
<serviceCertificate findValue="Contoso.com"
x509FindType="FindBySubjectName" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
The serviceCredentials element contains information about how the client is to be authenticated to the service. Within the serviceCredentials element, different elements are used, with each one related to a different credential type.
2. Issued Token Credentials
The main idea behind the
issued token credentials is to allow a third-party token granting
authority to perform the authentication process. The client requests a
token and then includes that token in the request to the WCF service.
The WCF service then hands that token to the token-granting authority
to retrieve information about the requester.
In the .NET world, one of the main users of this type of credential is CardSpace. CardSpace
provides a number of capabilities above and beyond token issuing, and
there are other services that can provide similar functionality.
However, CardSpace does provide a nice foundation for talking about an example. Figure 1 illustrates the flow between the WCF client and service and the token provider.
Because the WCF service is
part of the equation, look at what needs to occur on the service side
to handle issued tokens. The configuration takes place in the behaviors
for the service. Consider the following code sample from the service’s
configuration file:
<services>
<service name="UpdateService"
behaviorConfiguration="ServiceCredentials">
<endpoint address="" binding="wsHttpBinding"
bindingConfiguration="requireInfoCard"
contract="IUpdateService" >
<identity>
<certificateReference
findValue="545c3b8e97d99fd75c75eb52c6908320088b4f50"
x509FindType="FindByThumbprint"
storeLocation="LocalMachine"
storeName="My" />
</identity>
</endpoint>
</service>
</services>
<bindings>
<wsHttpBinding>
<binding name="requireInfoCard">
<security mode="Message">
<message clientCredentialType="IssuedToken" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="ServiceCredentials">
<serviceCredentials>
<serviceCertificate
findValue="545c3b8e97d99fd75c75eb52c6908320088b4f50"
x509FindType="FindByThumbprint"
storeLocation="LocalMachine"
storeName="My" />
<issuedTokenAuthentication allowUntrustedRsaIssuers="true" />
</serviceCredentials>
</behavior>
</serviceBehaviors>
</behaviors>
The first thing to note is the identity element (shown in bold) in the endpoint
section. This element allows a different endpoint to provide
authentication functionality to the service. In this particular case,
the enclosed certificateReference element provides the details of which authentication facility to use.
2.1. certificateReference Element
This particular element
indicates the certificate that should be provided to the client to
verify the service’s identity. Its placement within the identity
element of the endpoint should help clarify its purpose. However, the
real reason to concentrate on this element is because other elements
use the same attributes when referencing a certificate.
Referencing a certificate is really a two-step process. The first step is to define the store to be searched. The storeName attribute identifies the particular store that contains the certificate. Table 2 contains a list of the valid values, and their meanings, for this attribute.
Table 2. Values for the storeName Attribute
Value | Description |
---|
AddressBook | Store for use by other users |
AuthRoot | Store containing third-party certificate authorities (CAs) |
CertificateAuthority | Store for intermediate CAs |
Disallowed | Store for certificates that have been revoked |
My | Store for personal certificates |
Root | Store for trusted root CA certificates |
TrustedPeople | Store for certificates related to directly trusted people and resources |
TrustedPublisher | Store for certificates related to directly trusted publishers |
Two attributes are involved with actually performing the search. The X509FindType attribute specifies the type of search. Then the findValue attribute defines the value that is searched for. Table 3 lists the different types of searches that can be performed.
Table 3. Certificate Find Types
Value | Description |
---|
FindByThumbprint | Searches for the certificate that matches the thumbprint specified in the findValue attribute. |
FindBySubjectName | Searches for the certificate that matches the subject name specified in the findValue
attribute. It is possible that using this type of search will return
more than one certificate. The search is case-insensitive and looks for
any subject that contains the indicated value. |
FindBySubjectDistinguishedName | Searches for the certificate that matches the subject name specified in the findValue attribute. The difference between this search type and FindBySubjectName is that the specified value must match the distinguished name precisely. |
FindByIssuerName | Searches for the certificate that matches the issuer name specified in the findValue
attribute. It is possible that using this type of search will return
more than one certificate. The search is case-insensitive and looks for
any issuer name that contains the indicated value. |
FindByIssuerDistinguishedName | Searches for the certificate that matches the issuer name specified in the findValue attribute. The difference between this search type and FindByIssuerName is that the specified value must match the distinguished name precisely. |
FindBySerialNumber | Searches for the certificate that matches the serial number specified in the findValue
attribute. The serial number must be in reverse order because it is an
integer. The reason for needing to reverse the value is because the
serial number is stored with the least significant byte first. However,
if the serial number is specified as an integer, the least significant
byte is last, so to find the desired serial number by using an integer,
you need to reverse the bytes that appear in the serial number. |
FindByTimeValid | Searches for certificates that are valid as of the DateTime value specified in the findValue attribute. |
FindByTimeNotYetValid | Searches for certificates that are not yet valid as of the DateTime value specified in the findValue attribute. |
FindByTimeExpired | Searches for certificates that have expired as of the DateTime value specified in the findValue attribute. |
FindByTemplateName | Searches for certificates in which the template name matches the name provided in the findValue attribute. A template name is an X509 v3 extension that specifies the uses of the certificate. |
FindByApplicationPolicy | Searches for the certificate in which the findValue attribute matches either the application policy friendly name or the object identifier of the certificate. |
FindByCertificatePolicy | Searches for the certificate in which the findValue attribute matches either the friendly name or the object identifier of the certificate policy. |
FindByExtension | Searches for the certificate in which the findValue attribute matches a string describing the certificate’s extension. |
FindByKeyUsage | Searches for the certificate in which the findValue
attribute matches either a string representing the key usage or an
integer representing a bit mask containing all the requested key usages. |
FindBySubjectKeyIdentifier | Searches for the certificate in which the findValue attribute matches the string representing the subject key identifier in hexadecimal. |
Note: As a result of the way the search types are defined, the FindByTimeValue, FindByTimeNotYetValid, and FindByTimeExpired
types should each contain a unique set of certificates. When these sets
are merged, the combination should include all the certificates in the
store being searched.
In the specific example from the Section 8.3.2 section, the identity element is configured to request a SAMLToken from CardSpace.
This fact is not immediately obvious from merely examining the
configuration file. However, notice that the binding is set to use an
issued token to secure the message, and the certificate that is
referenced by the certificateReference element was provided by CardSpace. The fact that CardSpace was the source of the certificate is not visibly apparent.
In addition, the same certificate information is provided in the serviceCredentials element in the service behavior. As you will see shortly, the same certificate information is used in the client configuration.
3. Windows Credentials
As has already been
mentioned, Windows credentials are the default value for client
credentials with message security. On the client side, configuration
for using Windows credentials is straightforward. As always, you can do
it either declaratively or imperatively. Look at the declarative
version in the following configuration section:
<bindings>
<wsHttpBinding>
<binding name="messageSecurity">
<security mode="Message">
<message clientCredentialType="Windows"/>
</security>
</binding>
</wsHttpBinding>
</bindings>
The
imperative version is not much more complex. An example of how to set
the client credential type to Windows through code follows.
' VB
Dim proxy As New UpdateServiceClient()
proxy.ClientCredentials.Windows.ClientCredential = _
CredentialCache.DefaultCredentials
Proxy.ClientCredentials.Windows.AllowedImpersonationLevel = _
TokenImpersonationLevel.Impersonation
Proxy.ClientCredentials.Windows.AllowNtlm = False
// C#
UpdateServiceClient proxy = new UpdateServiceClient();
proxy.ClientCredentials.Windows.ClientCredential =
CredentialCache.DefaultCredentials;
proxy.ClientCredentials.Windows.AllowedImpersonationLevel =
TokenImpersonationLevel.Impersonation;
proxy.ClientCredentials.Windows.AllowNtlm = false;
As you can see, a number of other properties can be set with the Windows credentials.
3.1. AllowedImpersonationLevel
The allowedImpersonationLevel
attribute determines the types of impersonation the service can perform
on behalf of the client. This is a standard setting when Windows
credentials are passed between different processes or computers. The
concept of impersonation has to do with the security context under
which requests for certain resources are made.
3.2. AllowNtlm
The Windows NT LAN
Manager (NTLM) is an authentication protocol used on networks that
include earlier systems running Windows NT or standalone and workgroup
systems. The purpose of the AllowNtlm attribute is to determine the type of authentication used to validate the credentials. If AllowNtlm is set to false, the WCF service is forced to use Kerberos when it performs any Windows SSPI Negotiate authentication. When set to true, NTLM authentication is used if appropriate.
If
the WCF service is deployed in certain environments, where local
accounts or the workgroup in which the service is running require NTLM
authentication, setting this value to false
can result in authentication failures. Alternatively, if the WCF
service is deployed in a manner that requires mutual authentication,
the flag must be set to false because NTLM does not support this scenario (and Kerberos does support it).
Note:
Although Kerberos is the preferred choice because of the greater
security it provides (as compared to NTLM), NTLM is still supported by
WCF. If the network includes systems running versions of Windows NT 4.0
and earlier, or if the service is running on a standalone system, NTLM
must be allowed.
On the service side, the identity of the request is available through the OperationContext object. Specifically, the following code will retrieve the name of the Windows user who made the request:
' VB
Dim currentUser As String = _
OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name
// C#
String currentUser =
OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name;